/*
1:安装axios
2:导入axios
3:创建axios副本(配制一个基地址,基地址来源于环境变量)
4:定义请求拦截器
5:定义响应拦截器
6:暴露出去axios副本
*/
/*
token超时主动处理(不通过后端状态码作为判断依据)
1:后端告诉前端token超时的时间是多久
2:登陆完成就存储一个相应的时间(当前的时间戳)
3:每次调用接口前判断一下,超时没有,如果超时就按token超时处理方式处理
  注意需要删除本地存储的起始时间
*/

import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router' // router===this.$router
import CookiesJS from 'js-cookie'
const maxTime = 10000
// Message===this.$message
const _axios = axios.create({
  baseURL: process.env.VUE_APP_BASE_API
})
let allCancelFn = []
/*
路由跳转时要取消上一路由的所有接口请求
1:在request.js封装一个方法用于取消所有接口请求
2:在导航守卫的前置守卫中调用
*/
export function cancelAll () {
  allCancelFn = allCancelFn.filter(item => {
    item.fn()
    return false
  })
}

// 定义请求拦截器
_axios.interceptors.request.use(
  config => {
    // 添加token
    /*
    后端接口有二种模式：
    1：如果你调用的接口不需要token,你在这里加上了，它就报错
       a:定义一个用于添加token的参数(useToken:true)在调用接口接口配制中加上
       b:在请求拦截器中获取该参数的值，如果该值为true,就加上token
    2：如果你调用的接口不需要token,你在这里加上了，它也不报错
        直接加上就可以了
  */
    // if (config.useToken) {
    //   config.headers.Authorization = `Bearer ${store.state.user.token}`
    // }
    // if (isTimeout()) {
    //   store.commit('user/logout')
    //   CookiesJS.remove('startTime')
    //   Message.error('token超时了')
    //   router.push('/login')
    //   return Promise.reject(new Error('token超时了'))
    // }
    // 调用同一接口的取消方法,取消方法调用后,该项要删除
    // allCancelFn.forEach((item,index) => {
    //   if (item.url === config.url && item.method === config.method) {
    //     item.fn()
    //     allCancelFn.splice(index,1)
    //   }
    // })
    // 同一接口请求取消功能
    allCancelFn = allCancelFn.filter(item => {
      if (item.url === config.url && item.method === config.method) {
        item.fn()
        return false
      }
      return true
    })
    // 删除数组中某些项,最好做法是filter
    /*
    返回值=数组.filter(item=>{
      return boolean
      bollean为true:返回值就会有该项
               false,该项就不会出现在返回值里
    })
    */

    // window.console.log('allCancelFn', allCancelFn, config)
    config.headers.Authorization = `Bearer ${store.state.user.token}`
    config.cancelToken = new axios.CancelToken(cancenFn => {
      allCancelFn.push({
        fn: cancenFn,
        url: config.url,
        method: config.method
      })
    })
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
// 返回true:说明超时了,false说明没超时
function isTimeout () {
  if (CookiesJS.get('startTime')) {
    return Date.now() - CookiesJS.get('startTime') > maxTime
  } else {
    return false
  }
}
// 定义响应拦截器
_axios.interceptors.response.use(
  // 成功的处理  2开头表示成功
  res => {
    // 这里是成功处理
    if (res.data.success) {
      return res.data.data
    } else {
      // 失败处理  1:提示 2：中止后续代码的执行（中止.then执行，执行.catch）
      Message.error(res.data.message)
      return Promise.reject(new Error(res.data.message))
    }
  },
  // 失败的处理
  error => {
    /*
token超时处理:
1:删除token(vuex,cookie)
2:删除用户信息
4:提示一下,
3:跳转到登陆页
5:中止.then执行return Promise.reject(error)
*/
    if (
      error.response &&
      error.response.data &&
      error.response.data.code === 10002
    ) {
      // token超时了
      // store.commit('user/removeToken')
      // store.commit('user/removeUserInfo')
      store.commit('user/logout')
      Message.error(error.response.data.message)
      router.push('/login')
    }

    return Promise.reject(error)
  }
)
export default _axios
